import path from 'path';
import express, { Request, Response } from 'express';

import { QiniuOssService } from '../services/qiniu-oss.service';
import CloudFileService from '../services/db/cloud-file.service';
import { validator } from '../validators/validator';
import { OssUploadLocalFileValidator } from '../validators/oss.validator';
import { OssUploadLocalFileInterface } from '../interfaces/controllers/oss-controller.interface';
import { ControllerInterface, ReturnStatusCodeEnum } from '../interfaces/controller.interface';

const cloudFileService = new CloudFileService();

class OssController implements ControllerInterface {
  public path;

  public router = express.Router();

  constructor({ path }) {
    this.path = path;
    this.initRoutes();
  }

  private async initRoutes() {
    const p = this.path;
    this.router.get(`${p}`, this.homePage);
    this.router.get(`${p}/token`, this.getToken);
    this.router.get(`${p}/uploadLocalFile`, validator(OssUploadLocalFileValidator), this.uploadLocalFile);
    this.router.get(`${p}/uploadByStream`, this.uploadByReadableStream);
    this.router.post(`${p}/upload/callback`, this.uploadCallbackPost);
  }

  private homePage(req: Request, res: Response) {
    return res.send('<h1>hello, oss Page</h1>');
  }

  private getToken(req: Request, res: Response) {
    const qiniuOssService = new QiniuOssService();
    const token = qiniuOssService.getUploadToken();
    return res.send(`<h1>token ${token}</h1>`);
  }

  // 后台使用
  private async uploadLocalFile(req: Request, res: Response) {
    const query: OssUploadLocalFileInterface = req.query;

    const { fileName, filePath } = query;

    const newFilePath = path.resolve(__dirname, filePath);

    const qiniuOssService = new QiniuOssService();

    const result = await qiniuOssService.uploadLocalFile(fileName, newFilePath);

    if (result.statusCode === ReturnStatusCodeEnum.OK) {
      return res.json({
        status: result.statusCode
      });
    }
    return res.json({
      status: ReturnStatusCodeEnum.ERROR
    });
  }

  // 后台使用
  private async uploadByReadableStream(req: Request, res: Response) {
    const body: OssUploadLocalFileInterface = req.body;

    const { fileName, filePath } = body;

    const newFilePath = path.resolve(__dirname, filePath);

    const qiniuOssService = new QiniuOssService();

    const result = await qiniuOssService.uploadLocalFile(fileName, newFilePath);

    if (result.statusCode === ReturnStatusCodeEnum.OK) {
      return res.json({
        status: result.statusCode
      });
    }
    return res.json({
      status: ReturnStatusCodeEnum.ERROR
    });
  }

  private async uploadCallbackPost(req: Request, res: Response) {
    await cloudFileService.insert(req.body);
    res.json({ status: 200 });
  }

}

export default OssController;
